package com.ponhu.ea2.goodsCenter.provider.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ponhu.ea2.dto.PhPropertyValueDto;
import com.ponhu.ea2.entity.Material;
import com.ponhu.ea2.entity.PhInventoryPropertyValueMd;
import com.ponhu.ea2.entity.PhMaterialPropertyValueMd;
import com.ponhu.ea2.entity.PhProperty;
import com.ponhu.ea2.enums.PropertyTypeEnum;
import com.ponhu.ea2.enums.ResponseCodeEnum;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhCategoryMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhMaterialPropertyValueMdMapper;
import com.ponhu.ea2.goodsCenter.provider.mapper.PhPropertyMapper;
import com.ponhu.ea2.goodsCenter.provider.service.PhMaterialPropertyValueMdService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ponhu.ea2.goodsCenter.provider.service.PhPropertyService;
import com.ponhu.ea2.goodsCenter.provider.utils.CommonUtils;
import com.ponhu.ea2.goodsCenter.provider.utils.ProBeanUtils;
import com.ponhu.ea2.support.exception.BusinessRuntimeException;
import com.ponhu.ea2.vo.PhCategoryLevel3Vo;
import com.ponhu.ea2.vo.PhPropertyEditVo;
import com.ponhu.ea2.vo.PhPropertyVo;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 物料与属性值关系表 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2021-10-19
 */
@Service
public class PhMaterialPropertyValueMdServiceImpl
        extends ServiceImpl<PhMaterialPropertyValueMdMapper, PhMaterialPropertyValueMd>
        implements PhMaterialPropertyValueMdService {

    @Resource
    PhCategoryMapper phCategoryMapper;
    @Resource
    PhPropertyMapper phPropertyMapper;

    @Autowired
    private PhPropertyService phPropertyService;

    /**
     * 根据物料ID查询所有属性及属性值关系
     *
     * @param materialId
     * @return
     */
    @Override
    public List<PhMaterialPropertyValueMd> getPropertyValuesByMaterialId(Long materialId) {

        LambdaQueryWrapper<PhMaterialPropertyValueMd> queryWrapper = Wrappers
                .lambdaQuery(PhMaterialPropertyValueMd.class)
                .eq(PhMaterialPropertyValueMd::getMaterialId, materialId);

        return list(queryWrapper);
    }

    /**
     * 根据物料D查询所有属性
     *
     * @param materialId
     * @return
     */
    @Override
    public List<PhPropertyVo> getPropertyValueMap(Long materialId) {

        List<PhMaterialPropertyValueMd> mdList = getPropertyValuesByMaterialId(materialId);

        List<Long> propIds = mdList.stream().map(PhMaterialPropertyValueMd::getPropertyId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(propIds)) return Lists.newArrayList();

        Map<Long, String> propMap = phPropertyService.listByIds(propIds)
                .stream().filter(prop -> StringUtils.isNotBlank(prop.getSuffixPrompt()))
                .collect(Collectors.toMap(PhProperty::getId, PhProperty::getSuffixPrompt));
        if (MapUtils.isNotEmpty(propMap))
            mdList.stream().forEach(md ->
                    md.setPropertyValue(String.format("%s%s", md.getPropertyValue(),
                            propMap.getOrDefault(md.getPropertyId(), ""))));

        return CommonUtils.packagingPhPropertyVo(mdList);
    }

    @Override
    public void savePhmaterialProperty(List<PhPropertyValueDto> propertyList, Material material) {
        List<PhMaterialPropertyValueMd> list = new ArrayList<>();
        propertyList.stream().forEach(item -> {
            PhMaterialPropertyValueMd phMaterialPropertyValueMd = new PhMaterialPropertyValueMd();
            phMaterialPropertyValueMd.setMaterialId(material.getId());
            phMaterialPropertyValueMd.setPropertyId(item.getPropertyId());
            phMaterialPropertyValueMd.setPropertyName(item.getPropertyName());
            phMaterialPropertyValueMd.setValueId(item.getValueId());
            phMaterialPropertyValueMd.setPropertyValue(item.getPropertyValue());
            list.add(phMaterialPropertyValueMd);
        });
        saveBatch(list);
    }

    /**
     * 根据货品ID查询货品所属类目所有属性及属性值集合
     *
     * @param materialId
     * @param categoryId
     * @return
     */
    @Override
    public List<PhPropertyEditVo> getPropertyValueVos(String materialId, Long categoryId) {

        List<PhMaterialPropertyValueMd> materialPropertyValueMds = getPropertyValuesByMaterialId(Long.parseLong(materialId));

        Set<Long> propIdSet = materialPropertyValueMds.stream()
                .map(PhMaterialPropertyValueMd::getPropertyId).collect(Collectors.toSet());
        Set<Long> valueIdSet = materialPropertyValueMds.stream()
                .map(PhMaterialPropertyValueMd::getValueId).collect(Collectors.toSet());
        Map<Long, String> textPropMap = materialPropertyValueMds.stream().collect(
                Collectors.groupingBy(PhMaterialPropertyValueMd::getPropertyId,
                        Collectors.mapping(PhMaterialPropertyValueMd::getPropertyValue, Collectors.joining(","))));

        PhCategoryLevel3Vo phCategoryLevel3Vo = phCategoryMapper
                .getCategoryLevel3VosById(null, null, categoryId).stream().findFirst().get();
        List<Long> categoryIds = Arrays.asList(phCategoryLevel3Vo.getLevel1Id(),
                phCategoryLevel3Vo.getLevel2Id(), phCategoryLevel3Vo.getLevel3Id());

        return phPropertyMapper.getPropValuesByCategoryIds(PropertyTypeEnum.MATERIAL.getCode(), categoryIds)
                .stream().map(propVo -> {
                    propVo.getValueList().stream()
                            .forEach(value -> value.setChecked(valueIdSet.contains(value.getId())));
                    return propVo.setChecked(propIdSet.contains(propVo.getId()))
                            .setText(textPropMap.get(propVo.getId()));
                }).collect(Collectors.toList());
    }

    @Override
    public void updatePhmaterialProperty(List<PhPropertyValueDto> propertyList, Long materialId) {
        remove(Wrappers.lambdaUpdate(PhMaterialPropertyValueMd.class)
                .eq(PhMaterialPropertyValueMd::getMaterialId, materialId));

        if (CollectionUtils.isEmpty(propertyList)) {
            return;
        }

        List<PhMaterialPropertyValueMd> propValueMds = propertyList.stream().map(prop ->
                ProBeanUtils.copyProperties(prop, PhMaterialPropertyValueMd.class)
                        .setMaterialId(materialId)
        ).collect(Collectors.toList());

        if (!saveBatch(propValueMds)) {
            throw new BusinessRuntimeException(ResponseCodeEnum
                    .INVENTORY_PROP_EXCEPTION_800203);
        }
    }

    @Override
    public boolean removeMaterialProperty(Long materialId) {
        return remove(Wrappers.lambdaUpdate(PhMaterialPropertyValueMd.class)
                .eq(PhMaterialPropertyValueMd::getMaterialId, materialId));
    }
}
